package my.edu.model.User.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import my.edu.common.constant.MessageConstant;
import my.edu.common.domain.PageDTO;
import my.edu.common.domain.PageVO;
import my.edu.common.exception.AdminException;
import my.edu.common.exception.CanNotFoundException;
import my.edu.common.exception.UserLoginException;
import my.edu.common.utils.PageUtils;
import my.edu.common.utils.RedisUtils;
import my.edu.model.User.entity.Permission;
import my.edu.model.User.entity.RolePermission;
import my.edu.model.User.entity.UserRole;
import my.edu.model.User.entity.VO.RoleVO;
import my.edu.model.User.entity.dto.PermissionDTO;
import my.edu.model.User.entity.dto.RoleDTO;
import my.edu.model.User.mapper.RoleMapper;
import my.edu.model.User.entity.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private IRolePermissionService rolePermissionService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IPermissionService permissionService;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public List<String> getRoleNameByUserId(Long id) {
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>(Role.class);
        List<Role> list = wrapper
//                .selectAll(Role.class)可加可不加
                .leftJoin(UserRole.class, UserRole::getRoleId, Role::getId)
                .eq(UserRole::getUserId, id).list();
        return list.stream().map(Role::getDescription).toList();
    }

    @Override
    public PageVO<RoleVO> listVO(PageDTO page, String description, String name) {
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>();
        wrapper
                .selectAsClass(Role.class, RoleVO.class)
                .like(description!=null,Role::getDescription, description)
                .like(name!=null,Role::getName,name);
//                .selectCollection(Permission.class, RoleVO::getPermissionVOListList)
//                .leftJoin(RolePermission.class, RolePermission::getRoleId, Role::getId)
//                .leftJoin(Permission.class, Permission::getId, RolePermission::getPermissionId);

        Page<RoleVO> roleVOPage = baseMapper.selectJoinPage(new Page<>(page.getPage(), page.getSize()), RoleVO.class, wrapper);
        return PageUtils.toPage(roleVOPage);
    }

    @Override
    @Transactional
    public void updateByDTO(RoleDTO roleDTO) {
        if (roleDTO.getId() == 1) throw new AdminException("不能修改管理员权限");
        long count = count(Wrappers.<Role>lambdaQuery().eq(Role::getName, roleDTO.getName()).ne(Role::getId, roleDTO.getId()));
        if (count > 0) {
            throw new UserLoginException("角色已存在");
        }
        Role role = getById(roleDTO.getId());
        if (role == null) throw new CanNotFoundException(MessageConstant.CAN_NOT_FOUND);
        List<PermissionDTO> dtoPermissionList = roleDTO.getPermissionList();
        //删除原来的权限
        rolePermissionService.removeByRoleId(role.getId());
        //新增新的权限
        if (dtoPermissionList != null && !dtoPermissionList.isEmpty())
            rolePermissionService.saveBatchByRoleIAndPermissionId(roleDTO.getId(), dtoPermissionList);
        BeanUtil.copyProperties(roleDTO, role, "permissionNameList", "id");
        updateById(role);
        redisUtils.delete("permissionSet");
        redisUtils.delete("roleSet");
    }

    @Override
    @Transactional
    public void saveNew(RoleDTO roleDTO) {
        Role role = new Role();
        BeanUtil.copyProperties(roleDTO, role, "permissionNameList", "id");
        long count = count(Wrappers.<Role>lambdaQuery().eq(Role::getName, roleDTO.getName()));
        if (count > 0) {
            throw new UserLoginException("角色已存在");
        }
        save(role);
        rolePermissionService.saveBatchByRoleIAndPermissionId(role.getId(), roleDTO.getPermissionList());
    }

    @Override
    @Transactional
    public void removeRole(Long id) {
        List<UserRole> list = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getRoleId, id));
        if (!list.isEmpty()) {
            throw new UserLoginException("角色还有对应员工，不能删除！");
        } else {
            removeById(id);
            rolePermissionService.removeByRoleId(id);
        }
        redisUtils.delete("permissionSet");
        redisUtils.delete("roleSet");
    }

    @Override
    public RoleVO getVOone(Long id) {
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>();
        wrapper
                .selectAsClass(Role.class, RoleVO.class)
                .selectCollection(Permission.class, RoleVO::getPermissionVOListList)
                .leftJoin(RolePermission.class, RolePermission::getRoleId, Role::getId)
                .leftJoin(Permission.class, Permission::getId, RolePermission::getPermissionId)
                .eq(Role::getId, id);
        RoleVO roleVO = baseMapper.selectJoinOne(RoleVO.class, wrapper);
        return roleVO;
    }

    @Override
    public List<Role> getRoleByUserId(Long id) {
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>(Role.class);
        List<Role> list = wrapper
                .selectAll(Role.class)
                .leftJoin(UserRole.class, UserRole::getRoleId, Role::getId)
                .eq(UserRole::getUserId, id).list();
        return list;
    }
}
